/*!
 * \file frlog.h
 *
 * \brief log出力
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * log出力相关接口
 *
 * \version 2.0
 * \author zhengxd
 * \date 2014/11/11
 *
 */
#ifndef _FRLOG_H_
#define _FRLOG_H_

#include <string.h>
#include <stdlib.h>

#include "zlog.h"

/*!
 * zlog初始化
 *
 * \param p_conf_file    (配置文件名称)
 * \param p_cat_name     (配置文件中log规则名称)
 *
 * \return 0:成功\n
 *         非0:失败
 *
 */
extern int frlog_open(const char *p_conf_file, const char *p_cat);


/*!
 * 取得全局log句柄
 *
 * \param void
 *
 * \return zlog_category_t *:log句柄\n
 *
 */
extern zlog_category_t *frlog_get_hd(void);

/*!
 * 设置全局句柄
 *
 * \param p_st_hd    (log句柄)
 *
 */
extern void frlog_set_hd(void *p_st_hd);

/*!
 * 不带有文件名,行数，函数的debug出力
 *
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_debug1(const char *p_fmt , ...);

/*!
 * 不带有文件名,行数，函数的info出力
 *
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_info1(const char *p_fmt , ...);

/*!
 * 不带有文件名,行数，函数的warn出力
 *
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_warn1(const char *p_fmt , ...);

/*!
 * 不带有文件名,行数，函数的error出力
 *
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_error1(const char *p_fmt , ...);

/*!
 * 不带有文件名,行数，函数的fatal出力
 *
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_fatal1(const char *p_fmt , ...);

/*!
 * 带有文件名,行数，函数的debug出力
 *
 * \param p_file   (文件名)
 * \param i_line   (行数)
 * \param p_fun    (函数)
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_debug2(const char *p_file, int i_line
                       , const char *p_fun, const char *p_fmt , ...);

/*!
 * 带有文件名,行数，函数的info出力
 *
 * \param p_file   (文件名)
 * \param i_line   (行数)
 * \param p_fun    (函数)
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_info2(const char *p_file, int i_line
                      , const char *p_fun, const char *p_fmt , ...);

/*!
 * 带有文件名,行数，函数的warn出力
 *
 * \param p_file   (文件名)
 * \param i_line   (行数)
 * \param p_fun    (函数)
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_warn2(const char *p_file, int i_line
                      , const char *p_fun, const char *p_fmt , ...);

/*!
 * 带有文件名,行数，函数的error出力
 *
 * \param p_file   (文件名)
 * \param i_line   (行数)
 * \param p_fun    (函数)
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_error2(const char *p_file, int i_line
                       , const char *p_fun, const char *p_fmt , ...);

/*!
 * 带有文件名,行数，函数的fatal出力
 *
 * \param p_file   (文件名)
 * \param i_line   (行数)
 * \param p_fun    (函数)
 * \param p_fmt    (log出力格式)
 *
 */
extern void frlog_fatal2(const char *p_file, int i_line
                       , const char *p_fun, const char *p_fmt , ...);

/*!
 * zlog去初始化
 *
 * \return 0:成功\n
 *         非0:失败
 *
 */
extern void frlog_close();

#define FRLOG_TIME_DIFF     1000000
#define FRLOG_LIMIT_COUNT   1000

#ifdef FRDBG_NO_LOG
    #define FRLOG_DEBUG(fmt , args...)
    #define FRLOG_INFO(fmt, args...)
    #define FRLOG_WARN(fmt , args...)
    #define FRLOG_WARN_TIME(fmt , args...)
    #define FRLOG_WARN_LIMIT(fmt , args...)
    #define FRLOG_ERROR(fmt , args...)
    #define FRLOG_ERROR_TIME(fmt , args...)
    #define FRLOG_ERROR_LIMIT(fmt , args...)
    #define FRLOG_FATAL(fmt , args...)

    #define FRLOG_DEBUG_DETAIL(fmt,args...)
    #define FRLOG_INFO_DETAIL(fmt,args...)
    #define FRLOG_WARN_DETAIL(fmt,args...)
    #define FRLOG_WARN_DETAIL_TIME(fmt,args...)
    #define FRLOG_WARN_DETAIL_LIMIT(fmt,args...)
    #define FRLOG_ERROR_DETAIL(fmt,args...)
    #define FRLOG_ERROR_DETAIL_TIME(fmt,args...)
    #define FRLOG_ERROR_DETAIL_LIMIT(fmt,args...)
    #define FRLOG_FATAL_DETAIL(fmt,args...)
#else
    /* 不带文件名,行数,函数的LOG */
    #define FRLOG_DEBUG(fmt , args...) frlog_debug1(fmt, ##args)
    #define FRLOG_INFO(fmt, args...) frlog_info1(fmt, ##args)
    #define FRLOG_WARN(fmt , args...) frlog_warn1(fmt, ##args)
    /* 间隔1秒输出信息 */
    #define FRLOG_WARN_TIME(fmt , args...)   \
                {static struct timeval time_pre={0,0}; struct timeval time_cur;  \
                long time_diff = 0; gettimeofday(&time_cur,NULL); time_diff = frtime_diff(&time_pre,&time_cur);\
                if(time_diff> FRLOG_TIME_DIFF || (time_pre.tv_sec==0&&time_pre.tv_usec==0))    \
                {frlog_warn1(fmt, ##args); gettimeofday(&time_pre,NULL);}  \
                }
    /* 1000次输出一次 */
    #define FRLOG_WARN_LIMIT(fmt , args...)   \
                {static int i_count = 0;    \
                if(i_count%FRLOG_LIMIT_COUNT==0) \
                {frlog_warn1(fmt, ##args); i_count = 0;}  \
                i_count++;}
    #define FRLOG_ERROR(fmt , args...) frlog_error1(fmt, ##args)
    #define FRLOG_ERROR_TIME(fmt , args...)  \
                {static struct timeval time_pre={0,0}; struct timeval time_cur;  \
                long time_diff = 0; gettimeofday(&time_cur,NULL); time_diff = frtime_diff(&time_pre,&time_cur);\
                if(time_diff> FRLOG_TIME_DIFF || (time_pre.tv_sec==0&&time_pre.tv_usec==0))     \
                {frlog_error1(fmt, ##args); gettimeofday(&time_pre,NULL);}  \
                }
    #define FRLOG_ERROR_LIMIT(fmt , args...)  \
                {static int i_count = 0;    \
                if(i_count%FRLOG_LIMIT_COUNT==0) \
                {frlog_error1(fmt, ##args); i_count = 0;}  \
                i_count++;}
    #define FRLOG_FATAL(fmt , args...) frlog_fatal1(fmt, ##args)

    /* 带有文件名,行数,函数的LOG */
    #define FRLOG_DEBUG_DETAIL(fmt,args...) 		\
        frlog_debug2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args);

    #define FRLOG_INFO_DETAIL(fmt,args...) 		\
        frlog_info2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)
    #define FRLOG_WARN_DETAIL(fmt,args...) 		\
        frlog_warn2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)
    #define FRLOG_WARN_DETAIL_TIME(fmt,args...) 		\
            {static struct timeval time_pre={0,0}; struct timeval time_cur;  \
            long time_diff = 0; gettimeofday(&time_cur,NULL); time_diff = frtime_diff(&time_pre,&time_cur);\
            if(time_diff> FRLOG_TIME_DIFF || (time_pre.tv_sec==0&&time_pre.tv_usec==0))    \
            {frlog_warn2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args); gettimeofday(&time_pre,NULL);}  \
            }
    #define FRLOG_WARN_DETAIL_LIMIT(fmt,args...) 		\
                {static int i_count = 0;    \
                if(i_count%1000==0) \
                {frlog_warn2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args); i_count = 0;}  \
                i_count++;}
    #define FRLOG_ERROR_DETAIL(fmt,args...) 		\
        frlog_error2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)
	#define FRLOG_ERROR_DETAIL_TIME(fmt,args...) 		\
            {static struct timeval time_pre={0,0}; struct timeval time_cur;  \
            long time_diff = 0; gettimeofday(&time_cur,NULL); time_diff = frtime_diff(&time_pre,&time_cur);\
            if(time_diff> FRLOG_TIME_DIFF || (time_pre.tv_sec==0&&time_pre.tv_usec==0))    \
            {frlog_error2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args); gettimeofday(&time_pre,NULL);}  \
            }
    #define FRLOG_ERROR_DETAIL_LIMIT(fmt,args...) 		\
                {static int i_count = 0;    \
                if(i_count%1000==0) \
                {frlog_error2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args); i_count = 0;}  \
                i_count++;}
    #define FRLOG_FATAL_DETAIL(fmt,args...) 		\
        frlog_fatal2(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)
#endif

#endif
